package org.geometerplus.android.fbreader;

import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import org.geometerplus.android.util.UIUtil;
import org.geometerplus.fbreader.bookmodel.TOCTree;
import org.geometerplus.fbreader.fbreader.FBReaderApp;
import org.geometerplus.fbreader.library.Book;
import org.geometerplus.fbreader.library.Bookmark;
import org.geometerplus.fbreader.library.Library;
import org.geometerplus.zlibrary.core.application.ZLApplication;
import org.geometerplus.zlibrary.core.resources.ZLResource;
import org.geometerplus.zlibrary.core.tree.ZLTree;
import org.geometerplus.zlibrary.text.view.ZLTextWordCursor;
import org.geometerplus.zlibrary.ui.android.R;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.ViewSwitcher;

public class BookTocMarkActivity extends Activity {
	BookTocMarkActivity context = this;
	
	private static final int OPEN_ITEM_ID = 0;
	private static final int EDIT_ITEM_ID = 1;
	private static final int DELETE_ITEM_ID = 2;
	
	private Button back;
	private Button edit;
	
	private ViewSwitcher switcher;

	private Button tocButton;
	private Button markButton;
	private Boolean flag = true;
	
	private ListView tocListView;
	private ListView markListView;
	
	private TOCAdapter myAdapter;
	private ZLTree<?> mySelectedItem;
	
	List<Bookmark> AllBooksBookmarks;
	private final List<Bookmark> myThisBookBookmarks = new LinkedList<Bookmark>();
	private final ZLResource myResource = ZLResource.resource("bookmarksView");
	
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Thread.setDefaultUncaughtExceptionHandler(new org.geometerplus.zlibrary.ui.android.library.UncaughtExceptionHandler(this));
		
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.book_toc_mark);

		back = (Button) findViewById(R.id.back);
		
		switcher = (ViewSwitcher) findViewById(R.id.switcher);

		Animation in = AnimationUtils.loadAnimation(this, android.R.anim.fade_in);
		Animation out = AnimationUtils.loadAnimation(this, android.R.anim.fade_out);
		switcher.setInAnimation(in);
		switcher.setOutAnimation(out);

		tocListView = (ListView) findViewById(R.id.toclist);
		markListView = (ListView) findViewById(R.id.marklist);
		
		//tocListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,new String[]{"toc","toc1"}));
		//markListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_expandable_list_item_1,new String[]{"mark","mark1"}));
		
		tocButton = (Button) findViewById(R.id.tocButton);
		markButton = (Button) findViewById(R.id.markButton);

		tocButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				flag = true;
				switcher.showPrevious();
				tocButton.setBackgroundResource(R.drawable.bt_bmtab_on);
				markButton.setBackgroundResource(R.drawable.bt_bmtab_off);
			}
		});
		markButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				flag = false;
				switcher.showNext();
				markButton.setBackgroundResource(R.drawable.bt_bmtab_on);
				tocButton.setBackgroundResource(R.drawable.bt_bmtab_off);
			}
		});
		back.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				context.finish();
			}
		});
		
		// 目录相关
		final FBReaderApp fbreader = (FBReaderApp)ZLApplication.Instance();
		final TOCTree root = fbreader.Model.TOCTree;
		myAdapter = new TOCAdapter(root);
		final ZLTextWordCursor cursor = fbreader.BookTextView.getStartCursor();
		int index = cursor.getParagraphIndex();	
		if (cursor.isEndOfParagraph()) {
			++index;
		}
		TOCTree treeToSelect = fbreader.getCurrentTOCElement();
		myAdapter.selectItem(treeToSelect);
		mySelectedItem = treeToSelect;
		
		// 书签相关
		AllBooksBookmarks = Library.Instance().allBookmarks();
		Collections.sort(AllBooksBookmarks, new Bookmark.ByTimeComparator());

		if (fbreader.Model != null) {
			final long bookId = fbreader.Model.Book.getId();
			for (Bookmark bookmark : AllBooksBookmarks) {
				if (bookmark.getBookId() == bookId) {
					myThisBookBookmarks.add(bookmark);
				}
			}

			new BookmarksAdapter(markListView, myThisBookBookmarks, true);
		} 
	}

	private void invalidateAllViews() {
		markListView.invalidateViews();
		markListView.requestLayout();
		
	}
	
	private static final int PROCESS_TREE_ITEM_ID = 0;
	private static final int READ_BOOK_ITEM_ID = 1;

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		if(flag){
			final int position = ((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).position;
			final TOCTree tree = (TOCTree)myAdapter.getItem(position);
			switch (item.getItemId()) {
				case PROCESS_TREE_ITEM_ID:
					myAdapter.runTreeItem(tree);
					return true;
				case READ_BOOK_ITEM_ID:
					myAdapter.openBookText(tree);
					return true;
			}
			return super.onContextItemSelected(item);
		}else {
			final int position = ((AdapterView.AdapterContextMenuInfo)item.getMenuInfo()).position;
			final Bookmark bookmark = ((BookmarksAdapter)markListView.getAdapter()).getItem(position);
			switch (item.getItemId()) {
				case OPEN_ITEM_ID:
					gotoBookmark(bookmark);
					return true;
				case EDIT_ITEM_ID:
					final Intent intent = new Intent(this, BookmarkEditActivity.class);
					startActivityForResult(intent, 1);
					// TODO: implement
					return true;
				case DELETE_ITEM_ID:
					bookmark.delete();
					myThisBookBookmarks.remove(bookmark);
					AllBooksBookmarks.remove(bookmark);
					invalidateAllViews();
					return true;
			}
			return super.onContextItemSelected(item);
		}
	}

	private final class TOCAdapter extends ZLTreeAdapter {
		TOCAdapter(TOCTree root) {
			super(tocListView, root);
		}

		@Override
		public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
			final int position = ((AdapterView.AdapterContextMenuInfo)menuInfo).position;
			final TOCTree tree = (TOCTree)getItem(position);
			if (tree.hasChildren()) {
				menu.setHeaderTitle(tree.getText());
				final ZLResource resource = ZLResource.resource("tocView");
				menu.add(0, PROCESS_TREE_ITEM_ID, 0, resource.getResource(isOpen(tree) ? "collapseTree" : "expandTree").getValue());
				menu.add(0, READ_BOOK_ITEM_ID, 0, resource.getResource("readText").getValue());
			}
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			final View view = (convertView != null) ? convertView :
				LayoutInflater.from(parent.getContext()).inflate(R.layout.toc_tree_item, parent, false);
			final TOCTree tree = (TOCTree)getItem(position);
			view.setBackgroundColor(tree == mySelectedItem ? 0xff808080 : 0);
			setIcon((ImageView)view.findViewById(R.id.toc_tree_item_icon), tree);
			((TextView)view.findViewById(R.id.toc_tree_item_text)).setText(tree.getText());
			((TextView)view.findViewById(R.id.toc_tree_item_text)).setTextColor(0xFF191919);
			return view;
		}

		void openBookText(TOCTree tree) {
			final TOCTree.Reference reference = tree.getReference();
			if (reference != null) {
				finish();
				final FBReaderApp fbreader = (FBReaderApp)ZLApplication.Instance();
				fbreader.addInvisibleBookmark();
				fbreader.BookTextView.gotoPosition(reference.ParagraphIndex, 0, 0);
				System.out.println("reference.ParagraphIndex = " + reference.ParagraphIndex);
				fbreader.showBookTextView();
			}
		}

		@Override
		protected boolean runTreeItem(ZLTree<?> tree) {
			if (super.runTreeItem(tree)) {
				return true;
			}
			openBookText((TOCTree)tree);
			return true;
		}
	}
	
	private void addBookmark() {
		final FBReaderApp fbreader = (FBReaderApp)FBReaderApp.Instance();
		final Bookmark bookmark = fbreader.addBookmark(20, true);
		if (bookmark != null) {
			myThisBookBookmarks.add(0, bookmark);
			AllBooksBookmarks.add(0, bookmark);
			invalidateAllViews();
		}
	}

	private void gotoBookmark(Bookmark bookmark) {
		bookmark.onOpen();
		final FBReaderApp fbreader = (FBReaderApp)FBReaderApp.Instance();
		final long bookId = bookmark.getBookId();
		if ((fbreader.Model == null) || (fbreader.Model.Book.getId() != bookId)) {
			final Book book = Book.getById(bookId);
			if (book != null) {
				finish();
				fbreader.openBook(book, bookmark, null);
			} else {
				UIUtil.showErrorMessage(this, "cannotOpenBook");
			}
		} else {
			finish();
			fbreader.gotoBookmark(bookmark);
		}
	}

	private final class BookmarksAdapter extends BaseAdapter implements AdapterView.OnItemClickListener, View.OnCreateContextMenuListener {
		private final List<Bookmark> myBookmarks;
		private final boolean myCurrentBook;

		BookmarksAdapter(ListView listView, List<Bookmark> bookmarks, boolean currentBook) {
			myBookmarks = bookmarks;
			myCurrentBook = currentBook;
			listView.setAdapter(this);
			listView.setOnItemClickListener(this);
			listView.setOnCreateContextMenuListener(this);
		}

		public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo menuInfo) {
			final int position = ((AdapterView.AdapterContextMenuInfo)menuInfo).position;
			if (getItem(position) != null) {
				menu.setHeaderTitle(getItem(position).getText());
				menu.add(0, OPEN_ITEM_ID, 0, myResource.getResource("open").getValue());
				//menu.add(0, EDIT_ITEM_ID, 0, myResource.getResource("edit").getValue());
				menu.add(0, DELETE_ITEM_ID, 0, myResource.getResource("delete").getValue());
			}
		}

		public View getView(int position, View convertView, ViewGroup parent) {
			final View view = (convertView != null) ? convertView :
				LayoutInflater.from(parent.getContext()).inflate(R.layout.bookmark_item, parent, false);
			final ImageView imageView = (ImageView)view.findViewById(R.id.bookmark_item_icon);
			final TextView textView = (TextView)view.findViewById(R.id.bookmark_item_text);
			final TextView bookTitleView = (TextView)view.findViewById(R.id.bookmark_item_booktitle);

			final Bookmark bookmark = getItem(position);
			if (bookmark != null) {
				imageView.setVisibility(View.GONE);
				textView.setText(bookmark.getText());
				textView.setTextColor(0xFF191919);
				textView.setTextSize(15);
				if (myCurrentBook) {
					bookTitleView.setVisibility(View.GONE);
				} else {
					bookTitleView.setVisibility(View.VISIBLE);
					bookTitleView.setText(bookmark.getBookTitle());
					bookTitleView.setTextColor(0xFF191919);
				}
			}
			return view;
		}

		public final boolean areAllItemsEnabled() {
			return true;
		}

		public final boolean isEnabled(int position) {
			return true;
		}

		public final long getItemId(int position) {
			return position;
		}

		public final Bookmark getItem(int position) {
//			if (myCurrentBook) {
//				--position;
//			}
			return (position >= 0) ? myBookmarks.get(position) : null;
		}

		public final int getCount() {
			return myCurrentBook ? myBookmarks.size(): myBookmarks.size();
		}

		public final void onItemClick(AdapterView<?> parent, View view, int position, long id) {
			final Bookmark bookmark = getItem(position);
			if (bookmark != null) {
				gotoBookmark(bookmark);
			} else {
				//addBookmark();
			}
		}
	}
	
//	@Override
//	public boolean onKeyDown(int keyCode, KeyEvent event) {
//		if (keyCode == KeyEvent.KEYCODE_BACK) {
//			return true;
//		}
//		return super.onKeyDown(keyCode, event);
//	}

}